// 自定义切面模板demo

import { RefObject, useCallback, useEffect, useMemo, useRef, useState } from "react"
import { Popup } from 'antd-mobile';
import { ISearchData } from "../../../../designer/service"
import './index.less'
import { IOnRender } from "../category";
function Category({sectionList, entry, onSearch, getConvertSection, searchEngineData}: {
    sectionList:ISearchData["SectionList"]
    config: object
    entry: object
    configEvents: RefObject<Object>
    emit: Function
    searchEngineData: object
    getConvertSection: (data: string[]) => string
    onSearch: Function
}){
    //点击切面的层级, 用于清空切面数据
    const categoryLevel = useRef(-1);
    // 切面数据
    const [sectionDatas, $sectionDatas] = useState<ISearchData["SectionList"]>([]);
    // 处理切面数据
    useEffect(() => {
        const data = sectionList.map((item) => {
            if (item.sectionItemList?.length) {
                return {
                ...item,
                sectionItemList: [
                    {
                    Key: item.Key + ':',
                    isAll: true,
                    Value: '全部',
                    },
                    ...item.sectionItemList,
                ],
                } as ISearchData['SectionList'][number];
            } else {
                return item;
            }
        }).filter(item => !!item.sectionItemList?.length);

        $sectionDatas(section => {
            if (section.length === 0 || categoryLevel.current === -1) {
                return data
            } else {
                const newSectionList = data.filter(
                (ele, index) => index > categoryLevel.current,
                );
                const filterList = section.filter((ele, index) => index <= categoryLevel.current);
                const newList = [...filterList, ...newSectionList];
                return newList;
            }
        })
    }, [sectionList])

    // 切面选中的值
    const [selected, $selected] = useState<string[]>([]);
    // 选中切面的值触发的搜索
    const handleSelected = useCallback((key: string[], checked: boolean, isAll: boolean, IsWhether: boolean) => {
          if (isAll && !checked) {
            // 全部不能取消选中， 是根据子选项自动计算来的
            return;
          }
          $selected((selected) => {
            if (isAll) {
              return selected.filter((select) => select.indexOf(key[0]) === -1);
            } else {
              if (checked) {
                if (IsWhether) {
                  // 多选
                  return [...selected, ...key];
                } else {
                  // 单选
                  const categoryKey = key[0].split(':')[0] + ':';
                  return [...selected.filter((select) => select.indexOf(categoryKey) === -1), key[0]];
                }
              } else {
                return selected.filter((select) => select.indexOf(key[0]) === -1);
              }
            }
          });
        },
    []);

    // 弹框显示隐藏
    const [visible, $visible] = useState(false);
    // 展示切面详情
    const [sectionItem, $sectionItem] = useState<ISearchData['SectionList'][number] & {level?: number}>();

    useEffect(() => {
        if (visible === false) {
            $sectionItem(undefined)
        }
    }, [visible])
    // 搜索添加变更时， 关闭弹窗，清空选中项
    useEffect(() => {
        $sectionItem(undefined)
        $visible(false)
    }, [searchEngineData])

    //切面显示位置，用于获取弹框挂载节点定位
    const $headSection = useRef<HTMLUListElement>(null);
    // 弹框挂载节点
    const $popupBox = useRef<HTMLDivElement>(null);
    // 点击切面
    const handleClick = useCallback((data: ISearchData['SectionList'][number], level: number) => {
        //设置弹窗层的定位位置
        //@ts-ignore
        const {paddingLeft, paddingRight} = document.querySelector(`div[data-controlid="${entry.controlId}"] .inbiz-BizBody`)?.style || {paddingLeft: 0, paddingRight: 0}
        if ($popupBox.current) {
            $popupBox.current.style.left = '-' + paddingLeft;
            $popupBox.current.style.right = '-' + paddingRight;
            $popupBox.current.style.top = $headSection.current!.offsetTop + $headSection.current!.offsetHeight + 'px'
        }
        $sectionItem({...data, level})
        $visible(true)
    }, []);
    // 触发搜索
    const handleSearch = useCallback((level: number) => {
        categoryLevel.current = level;
        let newCategory = selected;
        const clearKeys = sectionDatas.map(item => item.Key).slice(level + 1);
        if (clearKeys?.length) {
            newCategory = selected.filter(item => {
                return !clearKeys.find(ckey => item.includes(ckey))
            });
            $selected(newCategory);
        }
        onSearch((old: any) => ({
            ...old,
            PageIndex: 0,
            SearchWhere: getConvertSection(newCategory)
        }));
    }, [selected]);

    
    const showPopupContent = useMemo(() => {
        return sectionItem ? <CategoryTopItemDetail 
            onOk={() => {
                handleSearch(sectionItem.level as number)
                $visible(false)
            }}
            selected={selected} 
            onSelected={handleSelected} 
            data={sectionItem}
        /> : null
    }, [sectionItem, selected, handleSelected]);

    return !!sectionDatas?.length  &&  <>
        <ul className='headSection' ref={$headSection}>
            {sectionDatas.map((item, index) => {
            return <CategoryTopItem isSelect={item.Key === sectionItem?.Key} item={item} key={item.Key} onClick={() => handleClick(item, index)}  />;
            })}
        </ul> 
        <div className="searchResultPopupBox" ref={$popupBox}></div>
        <Popup
            className="searchResultSectionPopup"
            visible={visible}
            position='top'
            onMaskClick={() => $visible(false)}
            getContainer={() => $popupBox.current || document.body}
        >
            <div className='searchResultSectionPopupContent'>{showPopupContent}</div>
        </Popup>
    </>
}   


function CategoryTopItem({
    item,
    onClick,
    isSelect
    }: {
    item: ISearchData['SectionList'][number];
    onClick: Function
    isSelect: boolean
}){
    return <li className={isSelect ? 'selected' : ''} onClick={() => onClick()}>{item.Value}</li>
}

function CategoryTopItemDetail({
    data,
    selected, 
    onSelected,
    onOk
}: {
    data: ISearchData['SectionList'][number];
} & Pick<IOnRender, 'onSelected' | 'selected' | 'onOk'>){
    const refOnOk = useRef<() => void>();
    refOnOk.current = onOk;
    const selectKeys = useMemo(() => {
        return selected.filter(item => item.includes(data.Key))
    }, [selected, data]);
    const handleClick = useCallback((sectionItem: typeof data["sectionItemList"][number], selectItem: boolean) => {
        onSelected([sectionItem.Key], !selectItem, sectionItem.isAll!, data.IsWhether)
        setTimeout(() => refOnOk.current?.(), 0)
    }, [onSelected, data]);
    return <ul className='searchResultTopSection'>{
        data.sectionItemList.map(item => {
            const selectItem = item.isAll ? selectKeys.length === 0 : selectKeys.includes(item.Key);
            return <li 
                key={item.Key}
                className={`ellipsis ${selectItem ? 'selected' : ''}`} 
                onClick={() => handleClick(item, selectItem)}
            >
                {selectItem && selectedImg}
                {item.Value}
            </li>
        })    
    }</ul>
}
//选中图标
const selectedImg = <svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 16 16">
<g id="ic-选择" transform="translate(-23 -241)">
  <rect id="矩形_19088" data-name="矩形 19088" width="16" height="16" transform="translate(23 241)" fill="none"/>
  <path id="路径_54374" data-name="路径 54374" d="M16,1.386a14.522,14.522,0,0,0-5.547,4.267,33.053,33.053,0,0,0-4.48,6.08A14.984,14.984,0,0,0,0,6.292L2.24,4.159A12.244,12.244,0,0,1,5.653,8.106,23.448,23.448,0,0,1,16,0V1.386Zm0,0" transform="translate(23 243.134)" fill="var(--inbiz-color-primary)"/>
</g>
</svg>

export default Category